import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:xws/helpers/safe_value_notifier.dart';
import 'package:xws/models/app_enum.dart';
import 'package:xws/utils/app_util.dart';
import 'package:xws/utils/log_util.dart';
import 'package:xws/utils/theme_util.dart';
import 'package:xws/utils/tools_util.dart';
import 'package:xws/widgets/back_icon.dart';

import 'ex_value_builder.dart';
import 'refresh_widget/empty_view.dart';
import 'refresh_widget/loading_view.dart';
import 'safe_appbar.dart';
import 'safe_scaffold.dart';

/// 应用webview封装
class AppWebView extends StatefulWidget {
  const AppWebView({
    Key? key,
    required this.url,
    this.isFullScreen = true,
    this.controller,
    this.pic = '',
    this.clearCache = true,
  }) : super(key: key);

  @override
  _AppWebViewState createState() => _AppWebViewState();

  final String url;
  final bool isFullScreen;
  final WVController? controller;
  final String pic;
  final bool clearCache;
}

class _AppWebViewState extends State<AppWebView> {
  /// 加载进度
  final SafeValueNotifier<int> _loadProgress = SafeValueNotifier<int>(0);

  /// 页面状态
  final SafeValueNotifier<PageState> _viewState = SafeValueNotifier<PageState>(PageState.normal);

  /// 标题
  final SafeValueNotifier<String> _title = SafeValueNotifier<String>('加载中');

  String _errMsg = '';

  InAppWebViewController? _controller;

  @override
  void initState() {
    super.initState();
    debug('打开地址:${widget.url}');
  }

  @override
  void dispose() {
    _loadProgress.dispose();
    _title.dispose();
    _viewState.dispose();
    super.dispose();
  }

  /// 重载
  Future<void> _reload({String? url}) async {
    _viewState.value = PageState.normal;

    if (url != null) {
      await _controller?.loadUrl(urlRequest: URLRequest(url: Uri.parse(url)));
    } else {
      await _controller?.reload();
    }
  }

  /// 后退
  Future<void> _back() async {
    if ((await _controller?.canGoBack()) ?? false) {
      await _controller?.goBack();
    } else {
      final NavigatorState navigator = Navigator.of(context);
      if (navigator.canPop()) pop(context);
    }
  }

  /// 监听web事件
  Future<void> _listenEvent(List<dynamic> args) async {
    if (args.isNotEmpty) {
      // final Map<String, dynamic> info = args[0] as Map<String, dynamic>;
      // final String action = info['action'] as String? ?? '';
    }
  }

  /// 创建webview回调
  Future<void> _onWebViewCreated(InAppWebViewController c) async {
    _controller = c;

    if (widget.controller != null) {
      widget.controller?.reload = _reload;
      widget.controller?.back = _back;
    }

    // if (widget.clearCache) await _controller?.clearCache();

    _controller?.addJavaScriptHandler(
      handlerName: 'xws',
      callback: _listenEvent,
    );
  }

  /// 加载错误
  Future<void> _onError(InAppWebViewController c, Uri? u, int code, String msg) async {
    error(msg + ' ' + widget.url);
    error('code:$code');

    if (code == -999) return;

    _errMsg = msg;
    _viewState.value = PageState.empty;
    await delayed(const Duration(milliseconds: 300));
    _title.value = '加载失败';
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        _back();
        return Future<bool>.value(false);
      },
      child: SafeScaffold(
        autoAppBar: false,
        appBar: widget.isFullScreen
            ? SafeAppBar(
                leading: BackIcon(onTap: _back),
                title: _buildTitle,
              )
            : null,
        body: _buildWebBody,
      ),
    );
  }

  /// 构建网站主体
  Widget get _buildWebBody {
    return Column(
      children: <Widget>[
        _buildProgress,
        Expanded(
          child: ExValueBuilder<PageState>(
            valueListenable: _viewState,
            child: InAppWebView(
              onTitleChanged: (_, String? title) => _title.value = title ?? '',
              initialUrlRequest: URLRequest(url: Uri.parse(widget.url)),
              onProgressChanged: (_, int pro) => _loadProgress.value = pro,
              onWebViewCreated: _onWebViewCreated,
              initialOptions: _initialOptions,
              onLoadError: _onError,
              onConsoleMessage: (_, ConsoleMessage consoleMessage) {
                debug('Console:' + consoleMessage.message);
              },
              shouldOverrideUrlLoading: (_, NavigationAction navigationAction) async {
                final Uri uri = navigationAction.request.url!;

                if (uri.scheme == 'tel') {
                  // final String tel = uri.toString().replaceAll('//', '+');
                  // try {
                  //   await launch(tel);
                  // } catch (e) {
                  //   debug('拨打号码失败');
                  // }

                  return NavigationActionPolicy.CANCEL;
                }

                return NavigationActionPolicy.ALLOW;
              },
            ),
            builder: (_, PageState p, Widget? c) {
              return IndexedStack(index: p.index, children: <Widget>[const LoadingView(), c!, _buildErr]);
            },
          ),
        ),
      ],
    );
  }

  ///构建错误视图
  Widget get _buildErr {
    return Center(
      child: EmptyView(
        content: widget.url + '\n' + _errMsg,
        onRefresh: (_) async => await _reload(),
      ),
    );
  }

  /// 构建标题
  Widget get _buildTitle {
    return ExValueBuilder<String>(
      valueListenable: _title,
      builder: (_, String t, __) => Text(
        t,
        style: Theme.of(context).appBarTheme.titleTextStyle,
      ),
    );
  }

  /// 构建加载进度条
  Widget get _buildProgress {
    return ExValueBuilder<int>(
      valueListenable: _loadProgress,
      builder: (_, int p, __) {
        return AnimatedContainer(
          duration: const Duration(milliseconds: 500),
          curve: Curves.ease,
          height: 2,
          width: sw * (p / 100),
          color: p == 100 ? canvas(context) : theme(context),
        );
      },
    );
  }

  /// webview配置
  InAppWebViewGroupOptions get _initialOptions => InAppWebViewGroupOptions(
        crossPlatform: InAppWebViewOptions(
          applicationNameForUserAgent: 'pptutor-webview',
          // cacheEnabled: widget.withCookie,
          // clearCache: !widget.withCookie,
          horizontalScrollBarEnabled: false,
          javaScriptCanOpenWindowsAutomatically: true,
          supportZoom: true,
          transparentBackground: true,
          useOnDownloadStart: true,
          useShouldOverrideUrlLoading: true,
          // preferredContentMode: useDesktopMode ? UserPreferredContentMode.DESKTOP : UserPreferredContentMode.RECOMMENDED,
          verticalScrollBarEnabled: false,
        ),
        android: AndroidInAppWebViewOptions(
          useHybridComposition: true,
          builtInZoomControls: true,
          displayZoomControls: false,
          // useShouldInterceptRequest: true,
          // forceDark: currentIsDark ? AndroidForceDark.FORCE_DARK_ON : AndroidForceDark.FORCE_DARK_OFF,
          loadWithOverviewMode: true,
          mixedContentMode: AndroidMixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW,
          safeBrowsingEnabled: false,
          supportMultipleWindows: false,
        ),
        ios: IOSInAppWebViewOptions(
          allowsAirPlayForMediaPlayback: true,
          allowsBackForwardNavigationGestures: true,
          allowsLinkPreview: true,
          allowsPictureInPictureMediaPlayback: true,
          isFraudulentWebsiteWarningEnabled: false,
        ),
      );
}

/// webview控制器
class WVController {
  /// 刷新网页
  Future<void> Function({String url})? reload;

  /// 回退
  Future<void> Function()? back;

  /// 销毁
  void dispose() {
    reload = null;
    back = null;
  }
}
